home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 49
/
Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso
/
Aminet
/
util
/
misc
/
ReportPlus.lha
/
ReportPlus
/
source
/
f10.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-04-16
|
44KB
|
1,259 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/dosextens.h>
#include <dos/exall.h>
#include <dos/datetime.h>
#include <graphics/gfx.h>
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/dos_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/exec_protos.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "rp.h"
#include "files.h"
#define ALL_REACTION_CLASSES
#include <reaction/reaction.h>
#define DRIVELENGTH 4 // the length of the base drive path
// (in this case, "SYS:")
MODULE void updatefiles(void);
MODULE void stage1(void);
MODULE void files_work(void); // for stage1()
MODULE void stage2(void);
MODULE void dobuffer(ULONG whichpen); // for stage2()
MODULE void stage3(void);
MODULE void stopping(STRPTR status);
MODULE void files_updatelog(void);
IMPORT ABOOL ram;
IMPORT SBYTE page;
IMPORT TEXT IOBuffer[LONGESTFIELD + 1],
aslresult[MEDFIELD + 1];
IMPORT ULONG increment;
IMPORT struct Screen* ScreenPtr;
IMPORT struct ExAllData* EADataPtr;
IMPORT struct VisualInfo* VisualInfoPtr;
IMPORT struct NewGadget Gadget;
IMPORT struct Menu* MenuPtr;
IMPORT Object* WinObject[FUNCTIONS + 1];
IMPORT struct Library *ButtonBase,
*CheckBoxBase,
*ChooserBase,
*IconBase,
*LabelBase,
*LayoutBase,
*ListBrowserBase,
*StringBase,
*WindowBase;
AGLOBAL struct Gadget* files_gadgets[GIDS_10 + 1];
MODULE struct List DirList,
FileList,
FileDateList,
FileTimeList,
ResultList,
EmptyResultList;
MODULE ABOOL ResultNodes = FALSE,
EmptyResultNodes = FALSE,
build = FALSE;
MODULE ULONG filesfound,
status = STATUS_READY;
MODULE TEXT datestringholder[LEN_DATSTRING],
timestringholder[LEN_DATSTRING];
MODULE struct
{ ULONG show[4]; // anything we want to use GetAttr() with must be ULONG
ULONG entries;
ULONG log, checkversion;
TEXT pathname[VLONGFIELD + 1];
} files =
{ TRUE, TRUE, TRUE, TRUE,
0, TRUE, TRUE, ""
};
MODULE BPTR LogFileHandle = NULL;
MODULE TEXT stringholder1[VLONGFIELD + 1],
stringholder2[VLONGFIELD + 1],
lockstring[VLONGFIELD + 1],
liststring[7][VLONGFIELD + 1];
MODULE struct ColumnInfo ResultColumnInfo[] =
{ { 28, // WORD ci_Width
"Pathname", // STRPTR ci_Title
0, // ULONG ci_Flags
},
{ 8,
"Date",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 8,
"Time",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 20,
"Version",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 8,
"Exp. Date",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 8,
"Exp. Time", // `Exp.' of course stands for `expected'
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ 20,
"Expected Version",
0, /* Last column must not have CIF_DRAGGABLE set (CIF_DRAGGABLE applies
to the right border of the relevant column). */
},
{ -1, (STRPTR) ~0, -1
} };
MODULE struct
{ ULONG red, green, blue, pennumber;
} penn[4] =
{ {0x55555555, 0xFFFFFFFF, 0x55555555, -1}, // green (OK) .
{0xFFFFFFFF, 0x88888888, 0x00000000, -1}, // orange (changed) !
{0x55555555, 0xFFFFFFFF, 0xFFFFFFFF, -1}, // cyan (3rd-party) +
{0xFFFFFFFF, 0x22222222, 0x22222222, -1}, // red (missing) -
};
// from rp.c
IMPORT SBYTE page;
IMPORT struct Window* MainWindowPtr;
IMPORT TEXT weekdaystring[LEN_DATSTRING],
datestring[LEN_DATSTRING],
timestring[LEN_DATSTRING];
AGLOBAL void files1(void)
{ struct Hook Hook10Struct;
BOOL inverse;
if (files.log)
{ inverse = FALSE;
} else
{ inverse = TRUE;
}
if (!files.pathname[0])
{ strcpy(files.pathname, "RAM:ReportPlus.log");
}
/* Create the window object. */
lockscreen();
gadtools();
InitHook(&Hook10Struct, Hook10Func, NULL);
if (!(WinObject[10] = NewObject(WINDOW_GetClass(), NULL,
// window
WA_PubScreen, ScreenPtr,
WA_ScreenTitle, "Report+",
WA_Title, "Report+: System Files Report",
WA_Activate, TRUE,
WA_DepthGadget, TRUE,
WA_DragBar, TRUE,
WA_CloseGadget, TRUE,
WA_SizeGadget, TRUE,
WA_IDCMP, IDCMP_RAWKEY,
WINDOW_IDCMPHook, &Hook10Struct,
WINDOW_IDCMPHookBits, IDCMP_RAWKEY,
WINDOW_MenuStrip, MenuPtr,
WINDOW_Position, WPOS_FULLSCREEN,
WINDOW_ParentGroup, files_gadgets[GID_10_LY1] =
NewObject(LAYOUT_GetClass(), NULL,
// root-layout
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_DeferLayout, TRUE,
LAYOUT_AddChild, NewObject(LAYOUT_GetClass(), NULL,
// layout
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_AddChild, NewObject(LAYOUT_GetClass(), NULL,
// layout
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_LEFT,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_AddImage,
NewObject
( LABEL_GetClass(), NULL,
LABEL_Text, "Show:",
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB1] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB1,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[0].pennumber,
GA_Text, "_OK (.)",
GA_Selected, (BOOL) files.show[0],
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB2] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB2,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[1].pennumber,
GA_Text, "_Changed (!)",
GA_Selected, (BOOL) files.show[1],
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB3] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB3,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[2].pennumber,
GA_Text, "_3rd-party (+)",
GA_Selected, (BOOL) files.show[2],
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_CB4] =
NewObject
( CHECKBOX_GetClass(), NULL,
GA_ID, GID_10_CB4,
GA_RelVerify, TRUE,
CHECKBOX_BackgroundPen, penn[3].pennumber,
GA_Text, "_Missing (-)",
GA_Selected, (BOOL) files.show[3],
TAG_END
),
CHILD_WeightedHeight, 0,
TAG_END
),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
// layout
LAYOUT_Orientation, LAYOUT_ORIENT_VERT,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_TOP,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_NONE,
LAYOUT_ShrinkWrap, TRUE,
LAYOUT_AddChild, files_gadgets[GID_10_CB5] =
NewObject
( CHECKBOX_GetClass(), NULL,
// checkbox
GA_ID, GID_10_CB5,
GA_RelVerify, TRUE,
GA_Text, "Check _versions?",
GA_Selected, (BOOL) files.checkversion,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, NewObject(LAYOUT_GetClass(), NULL,
// layout
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_ShrinkWrap, TRUE,
LAYOUT_AddChild, files_gadgets[GID_10_CB9] =
NewObject
( CHECKBOX_GetClass(), NULL,
// checkbox
GA_ID, GID_10_CB9,
GA_RelVerify, TRUE,
GA_Text, "_Log to:",
GA_Selected, (BOOL) files.log,
TAG_END
),
CHILD_WeightedWidth, 0,
LAYOUT_AddChild, files_gadgets[GID_10_ST1] =
NewObject(STRING_GetClass(), NULL,
// string
GA_ID, GID_10_ST1,
STRINGA_TextVal, files.pathname,
STRINGA_MinVisible,20,
GA_Disabled, inverse,
TAG_END
),
LAYOUT_AddChild, files_gadgets[GID_10_BU1] =
NewObject
( NULL, "button.gadget",
// button
GA_ID, GID_10_BU1,
GA_RelVerify, TRUE,
BUTTON_AutoButton,BAG_POPFILE,
GA_Disabled, inverse,
TAG_END
),
CHILD_WeightedWidth, 0,
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_FG1] =
NewObject
( FUELGAUGE_GetClass(), NULL,
GA_ID, GID_10_FG1,
GA_Text, "Ready.",
FUELGAUGE_Level, 0,
FUELGAUGE_Percent, FALSE,
FUELGAUGE_Justification,FGJ_CENTER,
TAG_END),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild,
NewObject
( LAYOUT_GetClass(), NULL,
// layout
LAYOUT_Orientation, LAYOUT_ORIENT_HORIZ,
LAYOUT_SpaceOuter, TRUE,
LAYOUT_VertAlignment, LALIGN_CENTER,
LAYOUT_HorizAlignment,LALIGN_CENTER,
LAYOUT_BevelStyle, BVS_FIELD,
LAYOUT_AddChild, files_gadgets[GID_10_BU2] =
NewObject
( NULL, "button.gadget",
// button
GA_ID, GID_10_BU2,
GA_RelVerify, TRUE,
GA_Text, "_Update",
TAG_END
),
CHILD_WeightedWidth, 50,
LAYOUT_AddChild, files_gadgets[GID_10_BU3] =
NewObject
( NULL, "button.gadget",
// button
GA_ID, GID_10_BU3,
GA_RelVerify, TRUE,
GA_Text, "Stop",
GA_Disabled, TRUE,
TAG_END
),
CHILD_WeightedWidth, 50,
TAG_END
),
CHILD_WeightedHeight, 0,
TAG_END
),
CHILD_WeightedHeight, 0,
TAG_END
),
CHILD_WeightedHeight, 0,
LAYOUT_AddChild, files_gadgets[GID_10_LB1] =
NewObject
( LISTBROWSER_GetClass(), NULL,
GA_ID, GID_10_LB1,
GA_ReadOnly, TRUE,
GA_TextAttr, Gadget.ng_TextAttr,
LISTBROWSER_Labels, (ULONG) &EmptyResultList,
LISTBROWSER_ColumnInfo, (ULONG) &ResultColumnInfo,
LISTBROWSER_ColumnTitles, TRUE,
LISTBROWSER_HorizontalProp,TRUE,
LISTBROWSER_VirtualWidth, 620 + 620,
TAG_END
),
CHILD_WeightedHeight, 100,
TAG_END
),
TAG_END
)))
{ rq("Can't create ReAction object(s)!");
}
unlockscreen();
openwindow();
loop();
closewindow();
files_exit();
}
MODULE void updatefiles(void)
{ ULONG i;
STRPTR stringptr;
/* Most gadgets are ghosted during the operation. Then their ghosting
status returns to normal (not necessarily unghosted).
0: Gadget handling.
1: Set up lists, do the directory examination.
(For each `source' directory in the `queue', before doing it
we check for a break. `Break opportunity 1'.)
At this point we have an empty DirList, and a full FileList, and an
empty ResultList.
2: Create the ResultList.
(For each `source' file in the `queue', before doing it we
check for a break. `Break opportunity 2'.)
3: Show results.
DirList: an Exec list of directories found, awaiting examination.
FileList: an Exec list of files found, awaiting processing.
ResultList: a listbrowser list of files found, for display.
Apparently the way strings work is that you get told an address where
the string is stored. This is apparently a pointer into system memory;
it doesn't need explicit allocation/deallocation by our appliprog. */
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST1], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.pathname, stringptr);
SetGadgetAttrs // `Update'
( files_gadgets[GID_10_BU2], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
SetGadgetAttrs // `Log to file?' (checkbox)
( files_gadgets[GID_10_CB9], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
/* For some reason, we need to explicitly refresh the checkbox gadget
visuals here */
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB9], MainWindowPtr, NULL);
SetGadgetAttrs // `Log to file:' (string)
( files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
SetGadgetAttrs // `Log to file:' (ASL button)
( files_gadgets[GID_10_BU1], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
for (i = 0; i <= 3; i++)
{ SetGadgetAttrs // `Show:'
( files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
/* For some reason, we need to explicitly refresh the checkbox gadget
visuals here */
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL);
}
SetGadgetAttrs // `Stop'
( files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
GA_Disabled, FALSE,
TAG_END
);
SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 16,
GA_Text, "Reading volume...",
TAG_END
); // we don't know how many files in advance...
SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, NULL,
TAG_END
);
SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, (ULONG) &EmptyResultList,
TAG_END
);
if (ResultNodes)
{ clearreactionlist(&ResultList);
ResultNodes = FALSE;
}
filesfound = 0;
status = STATUS_BUSY;
stage1();
if (status == STATUS_BUSY)
{ stage2();
}
FreeNameNodes(&FileList);
FreeNameNodes(&FileDateList);
FreeNameNodes(&FileTimeList);
if (status == STATUS_BUSY)
{ stage3();
}
status = STATUS_READY;
SetGadgetAttrs // `Update'
( files_gadgets[GID_10_BU2], MainWindowPtr, NULL,
GA_Disabled, FALSE,
TAG_END
);
SetGadgetAttrs // `Log to?' (checkbox)
( files_gadgets[GID_10_CB9], MainWindowPtr, NULL,
GA_Disabled, FALSE,
TAG_END
);
/* For some reason, we need to explicitly refresh the checkbox gadget
visuals here */
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB9], MainWindowPtr, NULL);
files_updatelog();
for (i = 0; i <= 7; i++)
{ SetGadgetAttrs // `Show'
( files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL,
GA_Disabled, FALSE,
TAG_END
);
/* For some reason, we need to explicitly refresh the checkbox gadget
visuals here */
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_CB1 + i], MainWindowPtr, NULL);
}
SetGadgetAttrs // `Stop'
( files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 0,
GA_Text, "Ready.",
TAG_END
);
}
MODULE void stage1(void)
{ struct NameNode* NodePtr;
NewList(&FileList);
NewList(&FileDateList);
NewList(&FileTimeList);
NewList(&DirList);
NewList(&ResultList);
AddNameToTail(&DirList, "");
// pop all the directories from the work stack, and send them one
// at a time to files_work() for processing.
while ((DirList.lh_Head)->ln_Succ) // while the list is non-empty
{ if (ra_checkbreak() == 1) // we don't yet support completely quitting
{ status = STATUS_STOPPING;
stopping("Stopping...");
break;
}
/* remove the dir-node from the list, copy its path to
stringholder1, call files_work, then free the dir-node. */
if (!(NodePtr = (struct NameNode *) RemTail(&DirList)))
{ rq("RemTail() failed (list is empty!)"); // this should never happen
}
strcpy(stringholder1, NodePtr->nn_Data);
files_work();
FreeMem(NodePtr, sizeof(struct NameNode));
}
FreeNameNodes(&DirList); // Not required unless stopping early (although harmless).
}
MODULE void stage2(void)
{ ABOOL matched;
ULONG filesdone = 0,
i,
length;
struct NameNode* NodePtr;
TEXT filename[VLONGFIELD + 1];
// Now we have the list of files.
// Everything is already allocated. Don't deallocate in this routine.
if (files.log)
{ if (!(LogFileHandle = (BPTR) Open(files.pathname, MODE_READWRITE)))
rq("Can't open file for appending!");
Seek(LogFileHandle, 0, OFFSET_END);
if (!build)
{ strcpy(IOBuffer, "AmigaOS system files at ");
getdate();
strcat(IOBuffer, timestring);
strcat(IOBuffer, " on ");
strcat(IOBuffer, weekdaystring);
strcat(IOBuffer, " ");
strcat(IOBuffer, datestring);
strcat(IOBuffer, ":\n\n");
if (Write(LogFileHandle, IOBuffer, strlen(IOBuffer)) == -1)
{ rq("Can't append to file!");
} } }
for (i = 0; i <= FILES; i++)
{ os[i].matched = FALSE;
}
/* status is always STATUS_BUSY at this point, because this function is
not called otherwise. */
SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, filesfound * 3,
FUELGAUGE_Level, filesfound,
GA_Text, "Examining...",
TAG_END
);
while ((FileList.lh_Head)->ln_Succ) // while the list is non-empty
{ if (ra_checkbreak() == 1)
{ status = STATUS_STOPPING;
stopping("Stopping...");
if (files.log)
{ strcpy(IOBuffer, "Aborted by user!");
if (Write(LogFileHandle, IOBuffer, strlen(IOBuffer)) == -1)
{ rq("Can't append to file!");
} }
break;
}
// assert(status != STATUS_STOPPING);
if (!(filesdone % 50))
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Level, filesfound + filesdone,
TAG_END
);
}
filesdone++;
if (!(NodePtr = (struct NameNode *) RemTail(&FileList)))
{ rq("RemTail() failed (list is empty!)"); // should never happen
}
strcpy(stringholder1, NodePtr->nn_Data);
length = strlen(stringholder1);
FreeMem(NodePtr, sizeof(struct NameNode));
if (!(NodePtr = (struct NameNode *) RemTail(&FileDateList)))
{ rq("RemTail() failed (list is empty!)"); // should never happen
}
strcpy(datestringholder, NodePtr->nn_Data);
FreeMem(NodePtr, sizeof(struct NameNode));
if (!(NodePtr = (struct NameNode *) RemTail(&FileTimeList)))
{ rq("RemTail() failed (list is empty!)"); // should never happen
}
strcpy(timestringholder, NodePtr->nn_Data);
FreeMem(NodePtr, sizeof(struct NameNode));
strcpy(filename, "SYS:");
strcat(filename, stringholder1);
// now get date of file
if (build)
{ strcpy(liststring[0], stringholder1);
strcpy(liststring[1], datestringholder);
strcpy(liststring[2], timestringholder);
getversion(filename, liststring[3]);
dobuffer(3);
} else
{ // now we have removed the file from the `queue', and copied its
// name into stringholder1. Now we check it against each system
// file.
matched = FALSE;
for (i = 0; i <= FILES; i++)
{ if (!matched && !(stricmp(stringholder1, os[i].pathname)))
{ // we have a match
matched = os[i].matched = TRUE;
strcpy(liststring[1], datestringholder);
strcpy(liststring[2], timestringholder);
strcpy(liststring[4], os[i].thedate);
strcpy(liststring[5], os[i].thetime);
if (files.checkversion)
{ getversion(filename, liststring[3]);
strcpy(liststring[6], os[i].version);
} else
{ strcpy(liststring[3], "?");
strcpy(liststring[6], "?");
}
if
( strcmp(os[i].thedate, liststring[1])
|| strcmp(os[i].thetime, liststring[2])
|| (files.checkversion && strcmp(os[i].version, liststring[3]))
)
{ strcpy(liststring[0], "!");
strcat(liststring[0], stringholder1);
if (files.show[1])
{ dobuffer(1);
} }
else
{ strcpy(liststring[0], ".");
strcat(liststring[0], stringholder1);
if (files.show[0])
{ dobuffer(0);
} }
break;
} }
if (files.show[2] && !matched) // third-party
{ strcpy(liststring[0], "+");
strcat(liststring[0], stringholder1);
strcpy(liststring[1], datestringholder);
strcpy(liststring[2], timestringholder);
if (files.checkversion)
{ getversion(filename, liststring[3]);
} else
{ strcpy(liststring[3], "?");
}
strcpy(liststring[4], "---");
strcpy(liststring[5], "---");
strcpy(liststring[6], "?");
dobuffer(2);
} } }
if (!build)
{ // missing files
if (status == STATUS_BUSY && files.show[3])
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 84,
GA_Text, "Handling missing...",
TAG_END
);
for (i = 0; i <= FILES; i++)
{ // For some reason this seems to cause problems
if (!(i % 50))
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Level, (FILES * 2) + i,
TAG_END
);
}
if (!os[i].matched)
{ strcpy(liststring[0], "-");
strcat(liststring[0], os[i].pathname);
strcpy(liststring[1], "---");
strcpy(liststring[2], "---");
strcpy(liststring[3], "---");
strcpy(liststring[4], os[i].thedate);
strcpy(liststring[5], os[i].thetime);
if (files.checkversion)
{ strcpy(liststring[6], os[i].version);
} else
{ strcpy(liststring[6], "?");
}
dobuffer(3);
} } } }
if (LogFileHandle)
{ Close(LogFileHandle); // Close() doesn't return an error code
LogFileHandle = NULL;
} }
MODULE void stage3(void)
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
FUELGAUGE_Min, 0,
FUELGAUGE_Max, 100,
FUELGAUGE_Level, 0,
GA_Text, "Ready.",
TAG_END
);
SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, NULL,
TAG_END
);
SetGadgetAttrs
( files_gadgets[GID_10_LB1], MainWindowPtr, NULL,
LISTBROWSER_Labels, (ULONG) &ResultList,
TAG_END
);
}
/* FileNamePtr[]: each of these is a pointer to the allocated memory
area holding the pathname of that file found (excepting "SYS:" portion).
FileNamesAllocated = number of elements of FileNamePtr[]. Or, another way
to think of it, the number of files on the SYS: partition. Element 0 of
the array is not used. */
MODULE void files_work(void)
{ BOOL more; // BOOL, not ABOOL
BPTR DirHandle; // = NULL;
struct ExAllControl* eac; // = NULL;
struct ExAllData* ead;
struct DateTime DateTime;
DateTime.dat_Format = FORMAT_DOS;
DateTime.dat_Flags = NULL;
DateTime.dat_StrDay = NULL;
DateTime.dat_StrDate = datestring;
DateTime.dat_StrTime = timestring;
/* Service routine for stage1(). Each call of this routine
handles one directory from the work stack. This routine is the one
that actually makes the DOS calls. It pushes any subdirectories
found onto the stack.
stringholder1 contains the pathname of the directory to examine
(without "SYS:").
lockstring contains the pathname of the directory to examine
(with "SYS:").
stringholder2 will contain the pathname of each file/dir found
(with "SYS:"). */
strcpy(lockstring, "SYS:");
strcat(lockstring, stringholder1);
if (!(DirHandle = (BPTR) Lock(lockstring, ACCESS_READ)))
{ // Printf("Can't lock %s!\n", lockstring);
rq("Can't lock directory!");
}
if (!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
{ UnLock(DirHandle);
DirHandle = NULL;
rq("Can't allocate DOS object!");
}
eac->eac_LastKey = 0;
do
{ more = ExAll(DirHandle, (struct ExAllData *) EADataPtr, 4096, ED_DATE, eac);
if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES))
{ FreeDosObject(DOS_EXALLCONTROL, eac);
eac = NULL;
UnLock(DirHandle);
DirHandle = NULL;
rq("Can't examine path!"); /* ExAll() failed abnormally */
}
if (eac->eac_Entries == 0)
{ ; /* ExAll() failed normally with no entries */
continue; /* more is USUALLY zero */
}
ead = (struct ExAllData *) EADataPtr;
do
{ /* use ead here */
strcpy(stringholder2, lockstring);
if (!AddPart(stringholder2, ead->ed_Name, VLONGFIELD))
{ FreeDosObject(DOS_EXALLCONTROL, eac);
eac = NULL;
UnLock(DirHandle);
DirHandle = NULL;
rq("Can't add filename/dirname to pathname!");
}
if (ead->ed_Type == 2) /* +2 is dir, +3 is softlink, -3 is file */
{ AddNameToTail(&DirList, &(stringholder2[DRIVELENGTH]));
} elif (ead->ed_Type == -3) // if it's a file
{ AddNameToTail(&FileList, &(stringholder2[DRIVELENGTH]));
DateTime.dat_Stamp.ds_Days = ead->ed_Days;
DateTime.dat_Stamp.ds_Minute = ead->ed_Mins;
DateTime.dat_Stamp.ds_Tick = ead->ed_Ticks;
DateToStr(&DateTime);
AddNameToTail(&FileDateList, datestring);
AddNameToTail(&FileTimeList, timestring);
filesfound++;
}
/* get next ead */
ead = ead->ed_Next;
} while(ead);
} while(more);
FreeDosObject(DOS_EXALLCONTROL, eac);
// eac = NULL;
UnLock(DirHandle);
// DirHandle = NULL;
}
MODULE void dobuffer(ULONG whichpen)
{ struct Node* ListBrowserNodePtr;
TEXT codestring[VLONGFIELD + 1], spaces[LONGFIELD + 1];
SLONG gap;
ULONG i;
/* Service routine for stage2(). */
if (!(ListBrowserNodePtr = AllocListBrowserNode
( 7, // columns,
LBNA_Column, 0,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, &liststring[0][1],
LBNA_Column, 1,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[1],
LBNA_Column, 2,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[2],
LBNA_Column, 3,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[3],
LBNA_Column, 4,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[4],
LBNA_Column, 5,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[5],
LBNA_Column, 6,
LBNA_Flags, LBFLG_CUSTOMPENS,
LBNCA_FGPen, BLACK,
LBNCA_BGPen, penn[whichpen].pennumber,
LBNCA_CopyText, TRUE,
LBNCA_Text, liststring[6],
TAG_END)))
{ rq("Can't create ReAction listbrowser.gadget node(s)!");
}
AddTail(&ResultList, ListBrowserNodePtr); // AddTail() has no return code
ResultNodes = TRUE;
if (files.log)
{ if (build)
{ strcpy(codestring, "{\""); // {"
strcat(codestring, liststring[0]);
strcat(codestring, "\", \""); // ", "
strcat(codestring, liststring[1]);
strcat(codestring, "\", \""); // ", "
strcat(codestring, liststring[2]);
strcat(codestring, "\", \""); // ", "
strcat(codestring, liststring[3]);
strcat(codestring, "\"},\n"); // "},
} else
{ strcpy(codestring, liststring[0]);
if (strlen(liststring[0]) >= 49)
{ strcat(codestring, "\n"
" "); // 50 spaces
} else
{ gap = 50 - strlen(liststring[0]);
for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
strcat(codestring, liststring[1]);
gap = 10 - strlen(liststring[1]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
strcat(codestring, liststring[2]);
gap = 9 - strlen(liststring[2]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
strcat(codestring, liststring[3]);
strcat(codestring, "\n"
" "); // 50 spaces
strcat(codestring, liststring[4]);
gap = 10 - strlen(liststring[4]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
strcat(codestring, liststring[5]);
gap = 9 - strlen(liststring[5]);
if (gap >= 1)
{ for (i = 0; i < gap; i++)
{ spaces[i] = ' ';
}
spaces[gap] = 0;
strcat(codestring, spaces);
}
strcat(codestring, liststring[6]);
strcat(codestring, "\n");
}
if (Write(LogFileHandle, codestring, strlen(codestring)) == -1)
{ rq("Can't append to file!");
} } }
AGLOBAL void files_init(void)
{ ULONG i;
struct Node* ListBrowserNodePtr;
lockscreen();
for (i = 0; i <= 3; i++)
{ penn[i].pennumber = FindColor
( ScreenPtr->ViewPort.ColorMap,
penn[i].red,
penn[i].green,
penn[i].blue,
-1
);
}
unlockscreen();
if (!(files.pathname[0]))
{ strcpy(files.pathname, "RAM:ReportPlus.log");
}
NewList(&ResultList);
NewList(&EmptyResultList);
if (!(ListBrowserNodePtr = AllocListBrowserNode
( 7, // columns
/* LBNCA_ tags are those that apply to the specific column. */
LBNA_Column, 0,
LBNA_Column, 1,
LBNA_Column, 2,
LBNA_Column, 3,
LBNA_Column, 4,
LBNA_Column, 5,
LBNA_Column, 6,
TAG_END
)))
{ rq("Can't create ReAction listbrowser.gadget node(s)!");
}
AddTail(&EmptyResultList, ListBrowserNodePtr); // AddTail() has no return code
EmptyResultNodes = TRUE;
}
AGLOBAL void files_exit(void)
{ // The window should be closed before calling this.
if (ResultNodes)
{ clearreactionlist(&ResultList);
ResultNodes = FALSE;
}
if (LogFileHandle)
{ Close(LogFileHandle); // Close() doesn't return an error code
LogFileHandle = NULL;
} }
AGLOBAL void files_die(void)
{ ULONG i;
IOBuffer[23] = (UBYTE) files.log;
for (i = 0; i <= 3; i++)
{ IOBuffer[i + 8] = (UBYTE) files.show[i];
}
IOBuffer[7] = (UBYTE) files.checkversion;
}
AGLOBAL void files_config(void)
{ UBYTE i;
files.log = (ULONG) IOBuffer[23];
for (i = 0; i <= 3; i++)
{ files.show[i] = (ULONG) IOBuffer[i + 8];
}
files.checkversion = (ULONG) IOBuffer[7];
}
AGLOBAL void files_loop(ULONG gid)
{ STRPTR stringptr;
switch (gid)
{
case GID_10_CB1:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB1], (ULONG *) &files.show[0]
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB2:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB2], (ULONG *) &(files.show[1])
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB3:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB3], (ULONG *) &files.show[2]
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB4:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB4], (ULONG *) &files.show[3]
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_CB5:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB5], (ULONG *) &files.checkversion
)))
{ rq("Unsupported inquiry!"); // should never happen
}
break;
case GID_10_ST1:
if (!(GetAttr
( STRINGA_TextVal, files_gadgets[GID_10_ST1], (ULONG *) &stringptr
)))
{ rq("Unsupported inquiry!"); // should never happen
}
strcpy(files.pathname, stringptr);
break;
case GID_10_BU1:
if (asl("~(#?.info)"))
{ strcpy(files.pathname, aslresult);
SetGadgetAttrs
( files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
STRINGA_TextVal, files.pathname,
TAG_END
);
}
break;
case GID_10_BU2:
updatefiles();
break;
case GID_10_CB9:
if (!(GetAttr
( GA_Selected, files_gadgets[GID_10_CB9], &files.log
)))
{ rq("Unsupported inquiry!"); // should never happen
}
files_updatelog();
if (files.log)
{ ActivateLayoutGadget(files_gadgets[GID_10_LY1], MainWindowPtr, NULL, (Object) files_gadgets[GID_10_ST1]);
}
break;
default:
break;
} }
AGLOBAL ULONG Hook10Func(struct Hook *h, VOID *o, VOID *msg)
{ /* "When the hook is called, the data argument points to the
window object and message argument to the IntuiMessage." */
UWORD code, qual;
ULONG scroll = 0;
geta4(); // wait till here before doing anything
code = ((struct IntuiMessage *) msg)->Code;
qual = ((struct IntuiMessage *) msg)->Qualifier;
switch(code)
{
case SCAN_HELP:
if (status == STATUS_READY)
{ helpabout();
}
break;
case SCAN_ESCAPE:
if (status == STATUS_READY)
{ if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
{ cleanexit(EXIT_SUCCESS);
} else page = 0;
} else
{ // assert(status == STATUS_BUSY);
status = STATUS_STOPPING;
}
break;
case SCAN_UP:
if (qual & IEQUALIFIER_CONTROL)
{ scroll = LBP_TOP;
} elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
{ scroll = LBP_PAGEUP;
} else scroll = LBP_LINEUP;
break;
case SCAN_DOWN:
if (qual & IEQUALIFIER_CONTROL)
{ scroll = LBP_BOTTOM;
} elif (qual & IEQUALIFIER_LSHIFT || qual & IEQUALIFIER_RSHIFT)
{ scroll = LBP_PAGEDOWN;
} else scroll = LBP_LINEDOWN;
break;
default:
break;
}
if (code == SCAN_UP || code == SCAN_DOWN)
{ SetGadgetAttrs
( files_gadgets[GID_10_LB1], // pointer to gadget
MainWindowPtr, // pointer to window (not window object!)
NULL, // pointer to requester
LISTBROWSER_Position, scroll, // tags
TAG_DONE // done
);
}
return(1);
}
MODULE void stopping(STRPTR status)
{ SetGadgetAttrs
( files_gadgets[GID_10_FG1], MainWindowPtr, NULL,
GA_Text, status,
TAG_END
);
SetGadgetAttrs // `Stop'
( files_gadgets[GID_10_BU3], MainWindowPtr, NULL,
GA_Disabled, TRUE,
TAG_END
);
}
MODULE void files_updatelog(void)
{ BOOL inverse;
if (files.log)
{ inverse = FALSE;
} else
{ inverse = TRUE;
}
SetGadgetAttrs // `Log to file:' (string)
( files_gadgets[GID_10_ST1], MainWindowPtr, NULL,
GA_Disabled, inverse,
TAG_END
);
/* For some reason, we need to explicitly refresh the string gadget
visuals here */
RefreshGadgets((struct Gadget *) files_gadgets[GID_10_ST1], MainWindowPtr, NULL);
SetGadgetAttrs // `Log to file:' (ASL button)
( files_gadgets[GID_10_BU1], MainWindowPtr, NULL,
GA_Disabled, inverse,
TAG_END
);
}